home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Just Call Me Internet
/
Just Call Me Internet.iso
/
prog
/
atari
/
m2
/
cat3src
/
magic
/
i
/
xbra.i
< prev
Wrap
Text File
|
1997-10-26
|
9KB
|
292 lines
(*----------------------------------------------------------------------*
* *
* MAGIC Modula's All purpose GEM Interface Cadre *
* ÿ ÿ ÿ ÿ ÿ *
*----------------------------------------------------------------------*
* Version 3.30 02.02.1992 (C)90/91/92 by Peter Hellinger Software *
*----------------------------------------------------------------------*
* Dieses Modul ist urheberrechtlich geschtzt. *
* *
* Die Verffentlichung des Quelltextes oder Teilen daraus in schrift- *
* licher Form, insbesondere in Zeitschriften, sowie die Verbreitung *
* ber Public-Domain-Hndler bedarf der ausdrcklichen schriftlichen *
* Genehmigung des Autors! *
* *
* Der Autor gibt hiermit die ausdrckliche Erlaubnis, das Modul jeder- *
* zeit auch im Quelltext weiterzugegeben, sofern dessen Text und ins- *
* besondere dieser Urheberrechts-Vermerk nicht verndert wird, und *
* durch die Weitergabe kein finanzieller Nutzen entsteht. Der Autor *
* behlt sich das Recht vor, diese Erlaubnis jederzeit u. ohne Angaben *
* von Grnden zu widerrufen. *
*----------------------------------------------------------------------*)
IMPLEMENTATION MODULE XBRA;
(* IMPLEMENTATION FR >>> Megamax-Modula-2 <<< *)
(* *)
(*$R- Range-Checks *)
(*$S- Stack-Check *)
(* *)
(*----------------------------------------------*)
(*
18.06.89 Thomas Tempelmann: Megamax-Version
04.07.89 Peter Hellinger: Umgearbeitet auf TDI
05.05.91 Peter Hellinger: Modul arbeitet jetzt unabhngig vom
verwendeten Compiler (MM2, TDI, SPC, LPR)
*)
IMPORT SYSTEM;
FROM MagicSys IMPORT CastToAddr, lWORD, sCARDINAL;
FROM MagicDOS IMPORT Super;
CONST JmpInstr = 4EF9H; (* Code fr 'JMP <adr>.L' *)
MODULE SysUtil1;
(*
* lokales Modul mit Funktionen zum Zugriff auf Daten im Supervisor-Modus
* ----------------------------------------------------------------------
*
* Die in diesem Modul verwendeten Funktionen
* SuperPeek, SuperLPeek und SuperLPoke
* dienen dazu, Daten im Supervisor-Mode zuzuweisen. Sie sind folgender-
* maen definiert:
* PROCEDURE SuperPeek ( addr: ADDRESS; VAR data: ARRAY OF BYTE );
* liest ab der Adresse 'addr' die Anzahl von 'HIGH (data)+1' Bytes.
* PROCEDURE SuperLPeek ( addr: ADDRESS ): LONGWORD;
* liefert 4 Bytes ab Adresse 'addr'.
* PROCEDURE SuperLPoke ( addr: ADDRESS; data: LONGWORD );
* weist 4 Bytes ab Adresse 'addr' zu.
* Diese Funktionen mssen auch korrekt ablaufen, wenn bereits bei ihrem
* Aufruf der Supervisor-Mode aktiv ist. Sie knnen wahlweise durch Verwen-
* dung der Funktion 'XBIOS.SuperExec' ('sup_exec()') oder mit 'GEMDOS.Super'
* ('super()') implementiert werden.
*)
IMPORT SYSTEM, CastToAddr, sCARDINAL, lWORD, Super;
EXPORT SuperPeek, SuperLPeek, SuperLPoke;
VAR from, to: POINTER TO SYSTEM.BYTE;
bytes: sCARDINAL;
stack: SYSTEM.ADDRESS;
PROCEDURE set;
VAR one: sCARDINAL;
BEGIN
one:= 1;
stack:= LONG (0);
Super (stack);
WHILE bytes > 0 DO
to^:= from^;
to:= CastToAddr (to) + CastToAddr (one);
from:= CastToAddr (from) + CastToAddr (one);
DEC (bytes)
END;
Super (stack);
END set;
PROCEDURE SuperPeek (addr: SYSTEM.ADDRESS; VAR data: ARRAY OF SYSTEM.BYTE);
BEGIN
from:= addr;
to:= SYSTEM.ADR (data);
bytes:= HIGH (data) + 1;
set; (* 'set' im Supervisor-Mode ausfhren *)
END SuperPeek;
PROCEDURE SuperLPeek ( addr: SYSTEM.ADDRESS ): lWORD;
VAR data: lWORD;
BEGIN
from:= addr;
to:= SYSTEM.ADR (data);
bytes:= 4;
set; (* 'set' im Supervisor-Mode ausfhren *)
RETURN data
END SuperLPeek;
PROCEDURE SuperLPoke ( addr: SYSTEM.ADDRESS; data: lWORD );
BEGIN
from:= SYSTEM.ADR (data);
to:= addr;
bytes:= 4;
set; (* 'set' im Supervisor-Mode ausfhren *)
END SuperLPoke;
END SysUtil1; (* lokales Modul *)
CONST Magic = 'XBRA';
entryOffs = 12; (* Differenz zw. 'Carrier.magic' und 'Carrier.entry' *)
(*
* Hilfsfunktionen, die ggf. optimiert werden knnen
* -------------------------------------------------
*)
PROCEDURE equal (s1, s2: ID): BOOLEAN;
VAR p1, p2: POINTER TO SYSTEM.ADDRESS; (* ein 4-Byte-Datentyp *)
BEGIN
p1:= SYSTEM.ADR (s1);
p2:= SYSTEM.ADR (s2);
RETURN p1^ = p2^
END equal;
PROCEDURE sub (p: SYSTEM.ADDRESS; n: sCARDINAL): SYSTEM.ADDRESS;
BEGIN
RETURN p - CastToAddr (n)
END sub;
(*
* Exportierte Funktionen
* ----------------------
*)
PROCEDURE Create (VAR use: Carrier; name: ID; call: SYSTEM.ADDRESS;
VAR entry: SYSTEM.ADDRESS);
BEGIN
use.name:= name;
use.magic:= Magic;
use.prev:= NIL;
use.entry.jmpInstr:= JmpInstr; (* Code fr 'JMP <adr>.L' *)
use.entry.operand:= call;
entry:= SYSTEM.ADR (use.entry)
END Create;
PROCEDURE Installed (name: ID; vector: SYSTEM.ADDRESS; VAR at: SYSTEM.ADDRESS): BOOLEAN;
VAR pc: POINTER TO Carrier;
entry: SYSTEM.ADDRESS;
c: Carrier;
lw: lWORD;
BEGIN
at:= vector; (* Vorwahl fr RETURN FALSE *)
LOOP
lw:= SuperLPeek (vector);
entry:= CastToAddr (lw);
IF entry = NIL THEN RETURN FALSE END;
pc:= sub (entry, entryOffs);
SuperPeek (pc, c);
IF equal (c.magic, Magic) THEN
(* XBRA-Kennung gefunden *)
IF equal (c.name, name) THEN at:= vector; RETURN TRUE;
ELSE vector:= sub (entry, 4);
END
ELSE
(* Ende, da XBRA-Kette zuende *)
RETURN FALSE
END;
END;
END Installed;
PROCEDURE Install (entry: SYSTEM.ADDRESS; at: SYSTEM.ADDRESS);
VAR pc: POINTER TO Carrier;
lw: lWORD;
BEGIN
IF (entry = NIL) OR (at = NIL) THEN
HALT
ELSE
pc:= sub (entry, entryOffs);
lw:= SuperLPeek (at);
pc^.prev:= CastToAddr (lw);
SuperLPoke (at, entry)
END
END Install;
PROCEDURE Remove (at: SYSTEM.ADDRESS);
VAR pc: POINTER TO Carrier;
entry: SYSTEM.ADDRESS;
c: Carrier;
lw: lWORD;
BEGIN
IF at = NIL THEN
HALT
ELSE
entry:= SYSTEM.ADDRESS( SuperLPeek (at));
IF entry = NIL THEN
HALT
ELSE
pc:= sub (entry, entryOffs);
SuperPeek (pc, c);
IF equal (c.magic, Magic) THEN SuperLPoke (at, c.prev);
ELSE HALT;
END
END
END
END Remove;
PROCEDURE Query (vector: SYSTEM.ADDRESS; with: QueryProc);
VAR pc: POINTER TO Carrier;
entry: SYSTEM.ADDRESS;
c: Carrier;
dummy: BOOLEAN;
lw: lWORD;
BEGIN
LOOP
lw:= SuperLPeek (vector);
entry:= CastToAddr (lw);
IF entry = NIL THEN RETURN END;
pc:= sub (entry, entryOffs);
SuperPeek (pc, c);
IF NOT equal (c.magic, Magic) THEN EXIT END;
IF NOT with (vector, c.name) THEN RETURN END;
(* Vorgnger ist dran *)
vector:= sub (entry, 4)
END;
dummy:= with (vector, '????')
END Query;
PROCEDURE Entry (at: SYSTEM.ADDRESS): SYSTEM.ADDRESS;
VAR lw: lWORD;
BEGIN
lw:= SuperLPeek (at);
RETURN CastToAddr (lw);
END Entry;
PROCEDURE Called (at: SYSTEM.ADDRESS): SYSTEM.ADDRESS;
VAR pc: POINTER TO Carrier;
entry: SYSTEM.ADDRESS;
c: Carrier;
lw: lWORD;
BEGIN
lw:= SuperLPeek (at);
entry:= CastToAddr (lw);
IF entry # NIL THEN
pc:= sub (entry, entryOffs);
SuperPeek (pc, c);
IF equal (c.magic, Magic) THEN
IF c.entry.jmpInstr = JmpInstr THEN
(* Wenn dies eine vom XBRA-Modul erzeugte Struktur ist, dann lie- *)
(* fern wir die Code-Adresse, die bei 'Install' angegeben wurde. *)
RETURN c.entry.operand
END
END;
(* Ansonsten wird einfach die direkte Einsprungadr. geliefert *)
RETURN entry
END;
RETURN NIL
END Called;
PROCEDURE PreviousEntry (entry: SYSTEM.ADDRESS): SYSTEM.ADDRESS;
VAR pc: POINTER TO Carrier;
BEGIN
IF entry # NIL THEN
pc:= sub (entry, entryOffs);
IF equal (pc^.magic, Magic) THEN RETURN pc^.prev END;
END;
RETURN NIL
END PreviousEntry;
END XBRA.